/**     
* @Title: ServletContentHandler.java   
* @Package me.springboot.netty.adapter   
* @Description: TODO
* @author weiwei 
* @date 2017年8月25日 下午2:55:30   
* @version V1.0     
*/
package me.springboot.netty.adapter;

import io.netty.channel.ChannelHandler.Sharable;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.handler.codec.http.DefaultFullHttpResponse;
import io.netty.handler.codec.http.DefaultHttpResponse;
import io.netty.handler.codec.http.HttpContent;
import io.netty.handler.codec.http.HttpRequest;
import io.netty.handler.codec.http.HttpResponse;
import io.netty.handler.codec.http.HttpResponseStatus;
import io.netty.handler.codec.http.HttpUtil;
import io.netty.handler.codec.http.HttpVersion;
import me.springboot.netty.context.NettyEmbeddedContext;
import me.springboot.netty.servlet.NettyHttpServletRequest;
import me.springboot.netty.servlet.NettyHttpServletResponse;
import me.springboot.netty.stream.HttpContentInputStream;

/**   
 * @ClassName: ServletContentHandler   
 * @Description: TODO 
 * @author weiwei
 * @date 2017年8月25日 下午2:55:30   
 *      
 */
@Sharable
public class ServletContentHandler extends ChannelInboundHandlerAdapter {
	
	private final NettyEmbeddedContext servletContext;
	
    private HttpContentInputStream inputStream; // FIXME this feels wonky, need a better approach

    public ServletContentHandler(NettyEmbeddedContext servletContext) {
        this.servletContext = servletContext;
    }

    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        inputStream = new HttpContentInputStream(ctx.channel());
    }

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        if (msg instanceof HttpRequest) {
            HttpRequest request = (HttpRequest) msg;
            HttpResponse response = new DefaultHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK, false);
            HttpUtil.setKeepAlive(response, HttpUtil.isKeepAlive(request));
            NettyHttpServletResponse servletResponse = new NettyHttpServletResponse(ctx, servletContext, response);
            NettyHttpServletRequest servletRequest = new NettyHttpServletRequest(ctx, servletContext, request, servletResponse, inputStream);
            if (HttpUtil.is100ContinueExpected(request)) {
                ctx.write(new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.CONTINUE), ctx.voidPromise());
            }
            ctx.fireChannelRead(servletRequest);
        }
        if (msg instanceof HttpContent) {
            inputStream.addContent((HttpContent) msg);
        }
    }

    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        inputStream.close();
    }
}
